#include "Pieza.h"

Pieza::Pieza(const string &hash, unsigned long int numeroPieza, unsigned long int tamanio, ManejadorArchivos* manejadorArchivos) {

	this->hash = hash;
	this->nroPieza = numeroPieza;
	this->tamanio = tamanio;
	this->manejadorArchivos = manejadorArchivos;
	this->cantEscrita = 0;
}

Pieza::~Pieza() {

}

bool Pieza::copiarBloque(const string &dato, unsigned long int offset) {

	unsigned long int offsetInicial = offset;
	unsigned long int offsetFinal = offset + dato.size() -1;

	/* Si encuentra que parte de la pieza ya fue escrita, retorna false */
	if (this->corroborarInterseccionOffsets(offsetInicial,offsetFinal)) {
		return false;
	}

	/* Actualiza la lista de offsets escritos */
	Offset nuevoOff;
	nuevoOff.offsetInicial = offsetInicial;
	nuevoOff.offsetFinal = offsetFinal;

	this->offsetsEscritos.push_back(nuevoOff);

	bool aux = this->manejadorArchivos->escribir(this->getNroPieza(), offset , dato);
	this->cantEscrita += dato.size();
	this->completa = (this->cantEscrita == this->tamanio);
	return aux;

}

unsigned long int Pieza::getNroPieza() const {

	return this->nroPieza;
}

unsigned long int Pieza::getTamanio() const {
	return this->tamanio;
}


unsigned long int Pieza::getCantidadEscrita() const {

	return this->cantEscrita;
}

string Pieza::getHash() const {

	return this->hash;
}

bool Pieza::estaCompleta() const {

	return this->completa;
}

bool Pieza::corroborarInterseccionOffsets(unsigned long int offsetInicial, unsigned long int offsetFinal) {

	list<Offset>::iterator it = this->offsetsEscritos.begin();
	bool encontrado = false;

	while ((!encontrado) && (it != this->offsetsEscritos.end())) {

		Offset actual = *it;
		it++;
		/* caso 1 */
		if ( (actual.offsetInicial >= offsetInicial) && (actual.offsetInicial <= offsetFinal)) {
			encontrado = true;
		}
		/* caso 2 */
		if ((actual.offsetInicial <= offsetInicial) && (actual.offsetFinal >= offsetFinal)) {
			encontrado = true;
		}
		/* caso 3*/
		if ((actual.offsetInicial < offsetInicial) && (offsetInicial < actual.offsetFinal)) {
			encontrado = true;
		}

		if ((actual.offsetInicial > offsetInicial) && (actual.offsetFinal < offsetFinal)) {
			encontrado = true;
		}
	}
   return encontrado;
}
